package com.hzjq.core.worker

import com.hzjq.core.BlastDelegate
import com.hzjq.core.ErrorCode
import com.hzjq.core.bean.CapProgressEntity
import com.hzjq.core.bean.ErrorReadCapEntity
import com.hzjq.core.bean.ErrorResult
import com.hzjq.core.callback.Callback
import com.hzjq.core.callback.ProgressCallback
import com.hzjq.core.massage.DataMessageBean
import com.hzjq.core.receive.Receiver
import com.hzjq.core.receive.Receives
import com.hzjq.core.work.Work
import io.reactivex.functions.Consumer

class BlastQueryWork : Work<CapProgressEntity> {

    private var blastTime = 0L
    private var maxDelay = 0L
    private var errorCallback: Consumer<ErrorReadCapEntity>?=null
    private var mBlastErrorWork:BlastErrorWork?=null

    constructor(maxDelay:Long,callback: Callback<CapProgressEntity>?,errorCallback: Consumer<ErrorReadCapEntity>) : super(callback){
       this.errorCallback = errorCallback
        if(maxDelay < BlastDelegate.getDelegate().getReceiveOutTime()){
           this.maxDelay = 12000
       } else {
           this.maxDelay = maxDelay
       }
    }

    override fun doWork(vararg args: Any) {
        if(args.size >= 2) {
            val isSuccess = args[0] as Boolean
            blastTime = args[1] as Long
            if(isSuccess) {
                Receives.getInstance()
                    .registerReceiver(BlastDelegate.getDelegate().getAssemblyCmdLoader().getBlastCycleQueryCmd(),
                        object : Receiver {
                            override fun convert(msg: String): Any {
                                return BlastDelegate.getDelegate().getParseLoader()
                                    .parseScanProgress(msg)
                            }

                            override fun onSuccess(msg: Any) {
                                if (msg is CapProgressEntity) {
                                    if(msg.total <= BlastDelegate.getDelegate().getMaxSupportCapCount()) {
                                        if (msg.progress < 100) {
                                            if (blastTime + maxDelay + BlastDelegate.getDelegate()
                                                    .getBlastOutTime() < System.currentTimeMillis()
                                            ) {
                                                onProgressChanged(50, "爆破超时")
                                                callback?.onError(ErrorCode.getErrorResult(-5))
                                                onDestroy()
                                            } else {
                                                if (msg.stateCode == 0) {
                                                    onProgressChanged(msg.progress / 2, "正在爆破")
                                                    callback?.onResult(msg)
                                                    retry(isSuccess, blastTime)
                                                } else {
                                                    if(msg.stateCode == 3){
                                                        onProgressChanged(100, "爆破失败")
                                                        callback?.onError(ErrorCode.getErrorResult(3))
                                                        onDestroy()
                                                    } else {
                                                        readErrorCap()
                                                    }
                                                }
                                            }
                                        } else {
                                            if (msg.stateCode == 0) {
                                                onProgressChanged(100, "起爆成功")
                                                callback?.onResult(msg)
                                            } else {
                                                if(msg.stateCode == 3){
                                                    onProgressChanged(100, "爆破失败")
                                                    callback?.onError(ErrorCode.getErrorResult(3))
                                                    onDestroy()
                                                } else {
                                                    readErrorCap()
                                                }
                                            }
                                        }
                                    } else {
                                        readErrorCap()
                                    }
                                }
                            }

                            override fun failed() {

                            }

                        })

                val msg = DataMessageBean(BlastDelegate.getDelegate().getAssemblyCmdLoader()
                    .getBlastCycleQueryCmd().cmd)
                BlastDelegate.getDelegate().getCmdExeLoader().exePollResultCmd(msg.assembly(),callback)
            } else {
                readErrorCap()
            }
        }
    }

    override fun cancel() {
        mBlastErrorWork?.cancel()
        Receives.getInstance()
            .unRegisterReceiver(BlastDelegate.getDelegate().getAssemblyCmdLoader()
                .getBlastCycleQueryCmd())
    }


    private fun readErrorCap(){
        mBlastErrorWork = BlastErrorWork(object : ProgressCallback<ErrorReadCapEntity> {
            override fun onResult(t: ErrorReadCapEntity) {
                errorCallback?.accept(t)
            }

            override fun onRetryCountChanged(retryCount: Int, action: String) {
                if(callback is ProgressCallback){
                    (callback as ProgressCallback<Boolean>).onRetryCountChanged(retryCount, action)
                }
            }

            override fun onError(errorCode: ErrorResult) {
                callback?.onError(errorCode)
            }

            override fun onProgressChanged(
                progress: Int,
                total: Int,
                action: String
            ) {
                if(callback is ProgressCallback){
                    (callback as ProgressCallback<Boolean>).onProgressChanged(progress, total, action)
                }
            }

        })
        mBlastErrorWork?.doWork()
    }
}